package com.example.mobifin_busticket;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Random;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.json.JSONArray;
import org.json.JSONObject;

import android.content.Context;
import android.net.Network;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;

import com.example.mobifin_busticket.controller.callbacks.ParseListner;
import com.example.mobifin_busticket.controller.callbacks.ResponseListener;
import com.example.mobifin_busticket.controller.databasemanager.DatabaseManager;
import com.example.mobifin_busticket.controller.networkmanager.NetworkManager;
import com.example.mobifin_busticket.models.BaseRequestEntityForBusTicketSeat;
import com.example.mobifin_busticket.models.BusModel;
import com.example.mobifin_busticket.models.CancellationTicketDetailsModel;
import com.example.mobifin_busticket.models.PassengerDetails;
import com.example.mobifin_busticket.models.RequestEntityBalanceCut;
import com.example.mobifin_busticket.models.RequestEntityUpdateTIN;
import com.example.mobifin_busticket.models.SeatDetailsModel;
import com.example.mobifin_busticket.models.SourceModel;
import com.example.mobifin_busticket.models.TicketDetailsModel;
import com.example.mobifin_busticket.views.activities.SeatBoardingInfoActivity;

public class BusTicketManagaer {

	private static final BusTicketManagaer INSTANCE = new BusTicketManagaer();
	Context mContext;
	String seatJson = null;
	String strAuthorizeKey = "";

	public static BusTicketManagaer getInstance() {
		return INSTANCE;
	}

	public void init() {
		Log.d("", "INIT RESELLER MANAGER");
	}

	// getAllsources based on SeatsellerApi of Sources
	public void getAllsources(final Context mContext,
			final ResponseListener listener, String consumerKey,
			String secretKey, String baseUrl, String tag) {
		this.mContext = mContext;
		final DatabaseManager dbManager1 = new DatabaseManager(mContext);

		// checking for sourcein database

		ArrayList<SourceModel> sourceList = dbManager1.getSourceFromDB();

		if (sourceList.size() > 0) {
			// we have source in db
			System.out.println("We have source in database");
			listener.onResponse(sourceList);
		} else {
			// we dont have source in db..need to place network call and insert
			// source in database
			System.out.println("We have made network call for source");

			BaseRequestEntityForBusTicketSeat requestEntityForBusTicket = new BaseRequestEntityForBusTicketSeat();
			requestEntityForBusTicket.setConsumerKey(consumerKey);
			requestEntityForBusTicket.setSecrateKey(secretKey);
			requestEntityForBusTicket.setUrl(baseUrl);

			ParseListner parseListnerofSources = new ParseListner() {
				@Override
				public Object onParse(String response) {

					try {
						// Parsing logic will goes here

						JSONObject json = new JSONObject(response);
						JSONArray cityArray = json.getJSONArray("cities");

						ArrayList<SourceModel> sourceList = new ArrayList<SourceModel>();
						for (int i = 0; i < cityArray.length(); i++) {
							JSONObject cityObj = cityArray.getJSONObject(i);
							String id = cityObj.getString("id");
							String name = cityObj.getString("name");

							SourceModel souce = new SourceModel();
							souce.setId(id);
							souce.setName(name);
							sourceList.add(souce);
							dbManager1.insertSources(id, name);
							System.out.println("inserted " + i + "record");

						}
						dbManager1.close();
						return sourceList;
					} catch (Exception e) {
						e.printStackTrace();
						return e;
					}

				}
			};

			// Call AsyncTask for Sources.
			new AsyncTaskForNetworkManager(mContext, requestEntityForBusTicket,
					parseListnerofSources, "test", "test") {
				@Override
				protected void onPostExecute(Object result) {
					super.onPostExecute(result);
					MyApplication.dismissProgressDialog();
					listener.onResponse(result);
				}
			}.execute();
		}
		
	}

	public void getDestination(Context dContext,
			final ResponseListener fetchDestination, String consumerkey,
			String secretkey, String URL, String tag) {
		// TODO Auto-generated method stub
		this.mContext = dContext;

		// we dont have source in db..need to place network call and insert
		// source in database
		System.out.println("We have made network call for source");

		BaseRequestEntityForBusTicketSeat requestEntityForBusTicket = new BaseRequestEntityForBusTicketSeat();
		requestEntityForBusTicket.setConsumerKey(consumerkey);
		requestEntityForBusTicket.setSecrateKey(secretkey);
		requestEntityForBusTicket.setUrl(URL);

		ParseListner parseListnerofDestination = new ParseListner() {
			@Override
			public Object onParse(String response) {

				try {
					// Parsing logic will goes here
					JSONObject json = new JSONObject(response);
					JSONArray cityArray = json.getJSONArray("cities");

					ArrayList<SourceModel> destinationList = new ArrayList<SourceModel>();
					for (int i = 0; i < cityArray.length(); i++) {
						JSONObject cityObj = cityArray.getJSONObject(i);
						SourceModel souce = new SourceModel();
						souce.setId(cityObj.getString("id"));
						souce.setName(cityObj.getString("name"));
						destinationList.add(souce);
						System.out.println("inserted " + i + "record");

					}

					return destinationList;
				} catch (Exception e) {
					e.printStackTrace();
					return e;
				}

			}
		};

		// Call AsyncTask for Sources.
		new AsyncTaskForNetworkManager(mContext, requestEntityForBusTicket,
				parseListnerofDestination, "test", "test") {
			@Override
			protected void onPostExecute(Object result) {
				super.onPostExecute(result);
				MyApplication.dismissProgressDialog();
				fetchDestination.onResponse(result);

			}
		}.execute();

	}

	public void getAllTrips(Context tripContext,
			final ResponseListener fetchAllTrips, String consumerkey,
			String secretkey, String Url, String tag) {
		// TODO Auto-generated method stub
		this.mContext = tripContext;

		System.out.println("We have made network call for Trips");

		BaseRequestEntityForBusTicketSeat requestEntityForBusTicket = new BaseRequestEntityForBusTicketSeat();
		requestEntityForBusTicket.setConsumerKey(consumerkey);
		requestEntityForBusTicket.setSecrateKey(secretkey);
		requestEntityForBusTicket.setUrl(Url);

		ParseListner parseListnerofTrips = new ParseListner() {

			@Override
			public Object onParse(String response) {

				System.out.println(response);
				saveDataIntoFile(response);
				ArrayList<BusModel> busList = BusModel
						.parseTripsDetails(response);
				DatabaseManager dbManager = new DatabaseManager(mContext);
				dbManager.deleteAllavailableTrips();
				dbManager.insertAllTrip(busList);
				dbManager.close();
				return busList;

				// final DatabaseManager dbManager = new
				// DatabaseManager(mContext);

			}
		};

		// Call AsyncTask for trips.
		new AsyncTaskForNetworkManager(mContext, requestEntityForBusTicket,
				parseListnerofTrips, "test", "test") {
			@Override
			protected void onPostExecute(Object busList) {
				super.onPostExecute(busList);
				MyApplication.dismissProgressDialog();
				fetchAllTrips.onResponse(busList);
			}
		}.execute();

	}

	protected void saveDataIntoFile(String response) {
		try {

			String root = Environment.getExternalStorageDirectory().toString();
			File myDir = new File(root + "/json");
			myDir.mkdirs();

			String fname = "mysdfile.txt";
			File myFile = new File(myDir, fname);

			myFile.createNewFile();
			FileOutputStream fOut = new FileOutputStream(myFile);
			final OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
			myOutWriter.append(response);
			myOutWriter.close();
			fOut.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void getAllSeatDetails(Context seatContext,
			final ResponseListener fetchAllTripsListener, String consumerkey,
			String secretkey, String url, String tag) {
		// TODO Auto-generated method stub
		this.mContext = seatContext;

		System.out.println("We have made network call for seatdetails");

		BaseRequestEntityForBusTicketSeat requestEntityForBusTicket = new BaseRequestEntityForBusTicketSeat();
		requestEntityForBusTicket.setConsumerKey(consumerkey);
		requestEntityForBusTicket.setSecrateKey(secretkey);
		requestEntityForBusTicket.setUrl(url);

		ParseListner parseListnerofTrips = new ParseListner() {

			@Override
			public Object onParse(String response) {
				saveDataIntoFile(response);

				System.out.println(response);
				saveDataIntoFile(response);
				ArrayList<SeatDetailsModel> seatList = SeatDetailsModel
						.parseTripsDetails(response);
				return seatList;

			}
		};

		// Call AsyncTask for trips.
		new AsyncTaskForNetworkManager(mContext, requestEntityForBusTicket,
				parseListnerofTrips, "test", "test") {
			@Override
			protected void onPostExecute(Object seatList) {
				super.onPostExecute(seatList);
				MyApplication.dismissProgressDialog();
				fetchAllTripsListener.onResponse(seatList);
			}
		}.execute();
	}

	public void setJSONObj(Context setJSONContext,
			final ResponseListener resonseFromServer, String consumerkey,
			String secretkey, String url, String strJSON, String tag) {
		// TODO Auto-generated method stub
		System.out.println("We have made network call for block key");
		BaseRequestEntityForBusTicketSeat requestEntityForBusTicket = new BaseRequestEntityForBusTicketSeat();
		requestEntityForBusTicket.setConsumerKey(consumerkey);
		requestEntityForBusTicket.setSecrateKey(secretkey);
		requestEntityForBusTicket.setUrl(url);
		String strgetJSON = strJSON;
		ParseListner pasreListener = new ParseListner() {

			@Override
			public Object onParse(String object) {
				// TODO Auto-generated method stub
				String strBlockkey = object.toString();
				System.out.println("Response on parse:" + strBlockkey);
				return object;
			}
		};

		new AsyncTaskForSendJSONObj(mContext, requestEntityForBusTicket,
				pasreListener, strgetJSON, "test", "Please wait...") {
			protected void onPostExecute(Object serverRespnse) {
				super.onPostExecute(serverRespnse);
				MyApplication.dismissProgressDialog();
				resonseFromServer.onResponse(serverRespnse);
			}
		}.execute();
	}

	public void deductResellerBalance(Context context, String passengerJSON,
			int no_of_passenger, double amount, String strBlockkey,
			final ResponseListener mobifindeductBalanceResponseListenrer) {
		// TODO Auto-generated method stub
		this.mContext = context;

		ParseListner pasreListener = new ParseListner() {

			@Override
			public Object onParse(String object) {
				// TODO Auto-generated method stub
				System.out.println("in pares listener response:" + object);

				return object;
			}
		};
		RequestEntityBalanceCut requestEntityForBusTicket = new RequestEntityBalanceCut();
		requestEntityForBusTicket.setConsumerKey(AppData.CONSUMERKEY);
		requestEntityForBusTicket.setSecrateKey(AppData.SECRETKEY);
		requestEntityForBusTicket.setUrl(AppData.product_host);
		requestEntityForBusTicket.setPassengerJSON(passengerJSON);
		requestEntityForBusTicket.setBlockKey(strBlockkey);
		requestEntityForBusTicket.setTotalPessanger(no_of_passenger);
		requestEntityForBusTicket.setAmount(amount);

		new AsyncTaskForMobifin(mContext, requestEntityForBusTicket,
				pasreListener, "", "Please Wait..") {
			@Override
			protected void onPostExecute(Object seatList) {
				super.onPostExecute(seatList);
				MyApplication.dismissProgressDialog();
				mobifindeductBalanceResponseListenrer.onResponse(seatList);
			}
		}.execute();

	}

	public void getTicketNoFromSeatSeler(Context ticketContext,
			final ResponseListener ticketNoResponseFromSeatSeller,
			String consumerkey, String secretkey, String url, String string2) {
		// TODO Auto-generated method stub
		this.mContext = ticketContext;

		System.out.println("We have made network call for ticketNo");

		BaseRequestEntityForBusTicketSeat requestEntityForBusTicket = new BaseRequestEntityForBusTicketSeat();
		requestEntityForBusTicket.setConsumerKey(consumerkey);
		requestEntityForBusTicket.setSecrateKey(secretkey);
		requestEntityForBusTicket.setUrl(url);
		ParseListner parseTicketNo = new ParseListner() {

			@Override
			public Object onParse(String objTicketNo) {
				// TODO Auto-generated method stub

				String[] splitTicketNo = objTicketNo.toString().split(";");
				System.out.println("Ticket no form parseListener:"
						+ splitTicketNo[1]);
				return splitTicketNo[1];
			}
		};

		new AsyncTaskForSendJSONObj(mContext, requestEntityForBusTicket,
				parseTicketNo, "", "", "Please Wait") {
			@Override
			protected void onPostExecute(Object ticketNo) {
				super.onPostExecute(ticketNo);
				MyApplication.dismissProgressDialog();
				ticketNoResponseFromSeatSeller.onResponse(ticketNo);
			}
		}.execute();

	}

	public void getTicketDetails(Context mcontext,
			final ResponseListener ticketDetailsResponseFromSeatSeller,
			String consumerkey, String secretkey, String url, String tag) {
		// TODO Auto-generated method stub
		this.mContext = mcontext;

		System.out.println("We have made network call for ticketNDetails");

		BaseRequestEntityForBusTicketSeat requestEntityForBusTicket = new BaseRequestEntityForBusTicketSeat();
		requestEntityForBusTicket.setConsumerKey(consumerkey);
		requestEntityForBusTicket.setSecrateKey(secretkey);
		requestEntityForBusTicket.setUrl(url);
		ParseListner parseTicketDetails = new ParseListner() {

			@Override
			public Object onParse(String objTicketDetails) {
				// TODO Auto-generated method stub

				System.out.println("Ticket Details response:\n"
						+ objTicketDetails.toString());
				saveDataIntoFile(objTicketDetails);
				ArrayList<TicketDetailsModel> ticketDetailsList = TicketDetailsModel
						.parseTicketDetails(objTicketDetails);

				return ticketDetailsList;
			}
		};
		new AsyncTaskForNetworkManager(mcontext, requestEntityForBusTicket,
				parseTicketDetails, "", "Please wait..") {
			@Override
			protected void onPostExecute(Object ticketDetails) {
				super.onPostExecute(ticketDetails);
				MyApplication.dismissProgressDialog();
				ticketDetailsResponseFromSeatSeller.onResponse(ticketDetails);
			}
		}.execute();
	}

	public void getCancellationTicketDetails(Context mcontext,
			final ResponseListener ticketDetailsResponseFromSeatSeller,
			String consumerkey, String secretkey, String url, String tag) {
		// TODO Auto-generated method stub
		this.mContext = mcontext;

		System.out
				.println("We have made network call for CancellationticketNDetails");

		BaseRequestEntityForBusTicketSeat requestEntityForBusTicket = new BaseRequestEntityForBusTicketSeat();
		requestEntityForBusTicket.setConsumerKey(consumerkey);
		requestEntityForBusTicket.setSecrateKey(secretkey);
		requestEntityForBusTicket.setUrl(url);
		ParseListner parseTicketDetails = new ParseListner() {

			@Override
			public Object onParse(String objTicketDetails) {
				// TODO Auto-generated method stub
				System.out.println("Cancellation Ticket Details response:\n"
						+ objTicketDetails.toString());
				saveDataIntoFile(objTicketDetails);
				ArrayList<CancellationTicketDetailsModel> ticketDetailsList = CancellationTicketDetailsModel
						.parseCancellationTicketDetails(objTicketDetails);

				return ticketDetailsList;
			}
		};
		new AsyncTaskForNetworkManager(mcontext, requestEntityForBusTicket,
				parseTicketDetails, "", "Please wait..") {
			@Override
			protected void onPostExecute(Object ticketDetails) {
				super.onPostExecute(ticketDetails);
				MyApplication.dismissProgressDialog();
				ticketDetailsResponseFromSeatSeller.onResponse(ticketDetails);
			}
		}.execute();
	}

	public void setCancelTicketJSONObj(Context mcontext,
			final ResponseListener cancelTicetResponse, String consumerkey,
			String secretkey, String url, String convertToJSON, String tag) {
		// TODO Auto-generated method stub
		System.out
				.println("We have made network call for cancle ticket respone");
		BaseRequestEntityForBusTicketSeat requestEntityForBusTicket = new BaseRequestEntityForBusTicketSeat();
		requestEntityForBusTicket.setConsumerKey(consumerkey);
		requestEntityForBusTicket.setSecrateKey(secretkey);
		requestEntityForBusTicket.setUrl(url);
		String strgetJSON = convertToJSON;
		ParseListner pasreListener = new ParseListner() {

			@Override
			public Object onParse(String object) {
				// TODO Auto-generated method stub
				String strCancelTicketResponse = object.toString();
				System.out.println("Response on parse:"
						+ strCancelTicketResponse);
				return object;
			}
		};

		new AsyncTaskForSendJSONObj(mContext, requestEntityForBusTicket,
				pasreListener, strgetJSON, "test", "test") {
			protected void onPostExecute(Object serverRespnse) {
				super.onPostExecute(serverRespnse);
				MyApplication.dismissProgressDialog();
				cancelTicetResponse.onResponse(serverRespnse);
			}
		}.execute();
	}

	// aa j function call thay che ne?
	public void sendEmailOrSMS(final Context mContext, String strEmail,
			String strSubject, String strMailbody, String strTag,
			String moNoMessage) {
		// TODO Auto-generated method stub
		Session session = createSessionObject();
		Message message = null;
		String[] moNoMessagesplit = moNoMessage.split(";");
		try {
			message = createMessage(strEmail, strSubject, strMailbody, session);
			new SendMailMessage.SendMailTask(mContext, strEmail,
					moNoMessagesplit[0], moNoMessagesplit[1], strTag)
					.execute(message);
		} catch (UnsupportedEncodingException e) {
			Log.e(AppData.TAG, e.toString(), e);
		} catch (MessagingException e) {
			Log.e(AppData.TAG, e.toString(), e);
		}
	}

	private Message createMessage(String email, String subject,
			String messageBody, Session session) throws MessagingException,
			UnsupportedEncodingException {
		Multipart multipart = new MimeMultipart("alternative");

		MimeBodyPart htmlpart = new MimeBodyPart();
		htmlpart.setContent(messageBody, "text/html");

		multipart.addBodyPart(htmlpart);

		Message message = new MimeMessage(session);

		message.setFrom(new InternetAddress(AppData.USERNAMEEMAIL,
				AppData.SHOPNAMETERMSEMAIL));

		message.addRecipient(Message.RecipientType.TO, new InternetAddress(
				email, email));
		message.setSubject(subject);
		message.setContent(multipart);
		return message;
	}

	// have run kar
	private Session createSessionObject() {
		Properties properties = new Properties();
		properties.put("mail.smtp.auth", "true");
		properties.put("mail.smtp.starttls.enable", "true");
		properties.put("mail.smtp.host", AppData.IPADDRESS);
		if (AppData.PORTNO.trim().length() > 0) {
			properties.put("mail.smtp.port", AppData.PORTNO);
		}
		return Session.getInstance(properties, new javax.mail.Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(AppData.USERNAMEEMAIL,
						AppData.PASSWORDEMAIL);
			}
		});
	}

	public void notifyTicketToMobifin(Context context,
			String tinForMobifin, String blockKeytoConfirm,
			String passengerJSON, final ResponseListener tinUpdateResponseListener) {

		
		
		this.mContext = context;

		ParseListner pasreListener = new ParseListner() {

			@Override
			public Object onParse(String object) {
				// TODO Auto-generated method stub
				System.out.println("in pares listener response:" + object);

				return object;
			}
		};
		RequestEntityUpdateTIN requestEntityForBusTicket = new RequestEntityUpdateTIN();
 		requestEntityForBusTicket.setUrl(AppData.product_host);
		requestEntityForBusTicket.setPassengerJSON(passengerJSON);
		requestEntityForBusTicket.setBlockKey(blockKeytoConfirm);
		requestEntityForBusTicket.setTin(tinForMobifin) ;
 
		new AsyncTaskForMobifin(mContext, requestEntityForBusTicket,
				pasreListener, "", "Please Wait..") {
			@Override
			protected void onPostExecute(Object seatList) {
				super.onPostExecute(seatList);
				MyApplication.dismissProgressDialog();
				tinUpdateResponseListener.onResponse(seatList);
			}
		}.execute();
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	}
}
